import { _decorator, Animation, CCBoolean, CircleCollider2D, Collider, Collider2D, Component, Contact2DType, ERigidBody2DType, FixedJoint2D, IPhysics2DContact, misc, Node, PhysicsSystem2D, Rect, RigidBody2D, sp, UITransform, v2, Vec2, Vec3 } from 'cc';
import { Player } from '../../Actor/Player/Player';
import { Physicsgroup } from '../../Actor/Config';
import { Enemy } from '../../Actor/Enemy/Enemy';
const { ccclass, property } = _decorator;

@ccclass('Sword_Skill_Controller')
export class Sword_Skill_Controller extends Component {
    private anim: Animation;
    private rb: RigidBody2D;
    private cd: CircleCollider2D;
    private player: Player;
    private isReturn: boolean = false;

    @property(CCBoolean) canRotate: boolean;

    private pierceAmount: number = 0;

    private IsBouncing: Boolean = false;
    private bounceAmount: number;
    private enemyTarget: Array<Enemy>;
    private targetIndex: number = 0;

    private IsSpinning: boolean = false;
    private maxTravelDistance: number;
    private spinDuration: number;
    private spinTimer: number;
    private wasStopped: boolean;

    private hitTimer: number;
    private hitCoolDown: number;

    private bounceSpeed: number = 4;
    private returnSpeed: number = 3;
    pos: Vec3 = null;
    updatePos: Vec3 = new Vec3();

    private destroyMe(){
        this.node.destroy();
    }
    protected onLoad(): void {
        this.anim = this.getComponentInChildren(Animation);
        this.rb = this.getComponent(RigidBody2D);
        this.cd = this.getComponent(CircleCollider2D);
        this.cd.on(Contact2DType.BEGIN_CONTACT, this.OnTriggerEnter2D, this)
    }
    setUpSword(_dir: Vec2, _gravity: number, _player: Player) {
        this.player = _player;
        this.rb.linearVelocity = _dir;
        this.rb.gravityScale = _gravity;

        if (this.pierceAmount <= 0)
            this.anim.play("SwordFlip");

        // setTimeout(() => {
        //     if(!this.isReturn){
        //         this.destroyMe();
        //         this.player.sword = null;
        //     }
        // }, 7000);
    }
    setupBounce(_isBouncing: boolean, _amountOfBounce) {
        this.IsBouncing = _isBouncing;
        this.bounceAmount = _amountOfBounce;
        this.enemyTarget = new Array<Enemy>();
    }
    setupPierce(_pierceAmount: number) {
        this.pierceAmount = _pierceAmount;
    }
    setupSpin(_isSpinning: boolean, _maxTravelDistance: number, _spinDuration: number,_hitCoolDown: number) {
        this.IsSpinning = _isSpinning;
        this.maxTravelDistance = _maxTravelDistance;
        this.spinDuration = _spinDuration;
        this.hitCoolDown = _hitCoolDown;
    }
    ReturnSword() {
        // this.rb.enabled = true;
        this.isReturn = true;

        this.canRotate = false;
        // this.rb.enabled = false;
        this.cd.enabled = false;

        this.rb.type = ERigidBody2DType.Kinematic;
        this.rb.linearVelocity = Vec2.ZERO;
        this.rb.angularVelocity = 0;
    }
    protected update(dt: number): void {
        if (this.canRotate) {
            this.setAngle();
        }


        if (this.isReturn) {
            Vec3.moveTowards(this.updatePos, this.node.getWorldPosition(), this.player.node.getWorldPosition(), this.returnSpeed);
            this.node.setWorldPosition(this.updatePos);
            if (Vec3.distance(this.player.node.worldPosition, this.node.worldPosition) < 10) {
                this.player.CatchSword();
            }
        } else if (this.pos != null) {// 保持子节点在父节点的相对位置
            this.node.setPosition(this.pos);
        }

        this.BounceLogic();
        this.SpinLogic(dt);
    }

    private SpinLogic(dt: number) {
        if (this.IsSpinning) {
            if (this.wasStopped) {
                this.spinTimer -= dt;
                if (this.spinTimer < 0) {
                    this.isReturn = true;
                    this.IsSpinning = false;
                }
            }
            if (!this.wasStopped && Vec3.distance(this.node.getWorldPosition(), this.player.node.getWorldPosition()) > this.maxTravelDistance) {
                this.wasStopped = true;

                this.rb.sleep();

                this.spinTimer = this.spinDuration;
            }
            this.hitTimer -= dt;
            if (this.hitTimer < 0) {
                this.hitTimer = this.hitCoolDown;

                let len = 50;
                const pos = this.node.getWorldPosition();
                const box = new Rect(pos.x - len, pos.y - len, len * 2, len * 2);

                const colliderList = PhysicsSystem2D.instance.testAABB(box);
                colliderList.forEach(hit => {
                    if (hit.getComponent(Enemy))
                        hit.getComponent(Enemy).damage();
                });

            }
        }
    }

    private BounceLogic() {
        if (this.IsBouncing && this.enemyTarget.length > 0) {

            Vec3.moveTowards(this.updatePos, this.node.getWorldPosition(), this.enemyTarget[this.targetIndex].node.getWorldPosition(), this.bounceSpeed);
            this.node.setWorldPosition(this.updatePos);
            if (Vec3.distance(this.enemyTarget[this.targetIndex].node.getWorldPosition(), this.node.worldPosition) < 0.5) {
                console.info(" " + this.enemyTarget + " " + this.bounceAmount);
                this.targetIndex++;
                this.bounceAmount--;
                if (this.bounceAmount <= 0) {
                    this.isReturn = true;
                    this.IsBouncing = false;
                }
                if (this.targetIndex >= this.enemyTarget.length) {
                    this.targetIndex = 0;
                }

            }
        }
    }

    OnTriggerEnter2D(selfCollider: Collider2D, otherCollider: Collider2D, contact: IPhysics2DContact | null) {
        if(this.isReturn)return;

        const enemy: Enemy = otherCollider.getComponent(Enemy);
        if(enemy){
            enemy?.damage();
            enemy.FreezeTimeFor(700);
        }
        

        this.setTargetForBounce(enemy);

        this.StuckInto(otherCollider);


    }
    private setTargetForBounce(enemy: Enemy) {
        if (enemy) {
            if (this.IsBouncing && this.enemyTarget.length <= 0) {
                let len = 100;
                const pos = enemy.node.getWorldPosition();
                const box = new Rect(pos.x - len, pos.y - len, len * 2, len * 2);

                const colliderList = PhysicsSystem2D.instance.testAABB(box);
                colliderList.forEach(hit => {
                    if (hit.getComponent(Enemy))
                        this.enemyTarget.push(hit.getComponent(Enemy));
                });
            }
        }
    }

    private StuckInto(otherCollider: Collider2D) {
        if (this.pierceAmount > 0 && otherCollider.getComponent(Enemy)) {
            this.pierceAmount--;
            return;
        }

        if (this.IsSpinning) {
            return;
        }

        this.scheduleOnce(() => {
            this.canRotate = false;
            this.cd.enabled = false;

            this.rb.type = ERigidBody2DType.Kinematic;
            this.rb.linearVelocity = Vec2.ZERO;
            this.rb.angularVelocity = 0;

        }, 0.01);

        if (this.IsBouncing && this.enemyTarget.length > 0)
            return;

        this.anim.play("SwordIdel")
        if (otherCollider.group == Physicsgroup.Enemy) {
            // 设置父节点
            this.node.setParent(otherCollider.node);
            this.scheduleOnce(() => {
                this.pos = this.node.getPosition();
            }, 0.01);
        }
    }

    setAngle() {
        const directionVec = this.rb.linearVelocity;
        // 计算节点当前朝向与目标朝向之间的夹角
        let curDir = v2(Math.cos(this.node.angle * Math.PI / 180), Math.sin(this.node.angle * Math.PI / 180));
        let angleToRotate = Math.atan2(directionVec.y, directionVec.x) - Math.atan2(curDir.y, curDir.x);
        // 将角度转换为度数，并四舍五入到最接近的整数
        let degreeToRotate = angleToRotate * 180 / Math.PI;
        // 设置节点的旋转角度，使其朝向目标方向
        this.node.angle = degreeToRotate + this.node.angle;
    }
}



